<script setup lang="ts">
import { nextTick, onMounted, reactive, ref } from 'vue'
import { roleAdd, roleEdit, roleSearch, roleDelete } from '@/api/role'
import { ElMessage, ElTree } from 'element-plus'
import useInstance from '@/hooks/userInstance'
import throttle from 'lodash/throttle'
//获取全局global
const { global } = useInstance()
//表单绑定的对象
const searchParm = reactive({
  currentPage: 1,
  pageSize: 10,
  roleName: '',
  total: 0
})
//菜单树的ref属性
const assignTree = ref()
//新增表单对象
const addModel = reactive({
  roleId: '',
  roleName: '',
  roleComment: ''
})
//重置表单数据
const resetForm = () => {
  addModel.roleName = ''
  addModel.roleComment = ''
}
//新增表单属性
const addRef = ref()
//表单规则
const rules = ref({
  roleName: [{ required: true, message: '请输入角色名称', trigger: 'blur' }],
  roleComment: [{ required: true, message: '请输入角色备注', trigger: 'blur' }]
})
//判断是新增还是编辑,0为新增，1为编辑
const tags = ref('')
//新增弹窗开关状态
let addFormShow = ref(false)
//表单标题
let menuTitle = ref('')
//表格高度
const tableHigh = ref(0)

//搜索
const searchBtn = () => {}
//重置
const resetBtn = () => {
  searchParm.roleName = ''
  searchParm.currentPage = 1
  roleGet()
}
//新增按钮
const addBtn = () => {
  tags.value = '0'
  addFormShow.value = true
  addModel.roleComment = ''
  addModel.roleName = ''
  menuTitle.value = '新增菜单'
}
//编辑按钮
const editBtn = throttle(row => {
  addModel.roleId = row.id
  tags.value = '1'
  addFormShow.value = true
  menuTitle.value = '编辑菜单'
  //回显数据
  addModel.roleName = row.name
  addModel.roleComment = row.comment
}, 1000)
//删除按钮
const deleteBtn = throttle(async role => {
  const confirm = await global.$myConfirm('确定要删除吗？')
  let roleId = role.id
  if (confirm) {
    await roleDelete(roleId)
    ElMessage.success('删除成功')
    await roleGet()
  }
}, 1000)

//分配权限按钮
const assignBtn = throttle(async row => {
  commitParm.roleId = row.id
  assignTreeData.list = []
  assignTreeData.assignTreeChecked = []
  parms.roleId = row.id
  parms.userId = store.info.id
  assignTitle.value = '为[' + row.comment + ']分配权限'
  assignFormShow.value = true
  await getAssignTree()
  console.log('打开了')
}, 3000)

//页容量改变时触发
const sizeChange = size => {
  searchParm.pageSize = size
  roleGet()
}
//页码改变时触发
const currentChange = page => {
  searchParm.currentPage = page
  roleGet()
}
//表单提交
const submitForm = () => {
  addRef.value.validate(async valid => {
    if (valid) {
      addFormShow.value = false
      if (tags.value === '0') {
        await roleAdd(addModel)
        ElMessage.success('添加角色成功')
      } else {
        await roleEdit(addModel)
        ElMessage.success('编辑角色成功')
      }
      resetForm()
      await roleGet()
    }
  })
}
//表单关闭
const closeForm = () => {
  addFormShow.value = false
  resetForm()
}

const roleGet = async () => {
  let result = await roleSearch()
  searchParm.total = result.data.length
  roleList.value = result.data
}

let roleList = ref([])

//分配权限弹窗开始
import { getAssignTreeApi } from '@/api/user'
import useUserInfoStore from '@/stores/userInfo'
import { saveMenuApi } from '@/api/role'
const treeRef = ref()

//树数据
const assignTreeData = reactive({
  list: [],
  assignTreeChecked: []
})
let assignTitle = ref('')
const store = useUserInfoStore()
//新增弹窗开关状态
let assignFormShow = ref(false)
//树的属性配置
const defaultProps = {
  children: 'children',
  label: 'comment'
}
//树数据查询参数
const parms = reactive({
  userId: '',
  roleId: ''
})
const getAssignTree = async () => {
  let res = await getAssignTreeApi(parms)
  if (res) {
    assignTreeData.list = res.data.permissionList
    assignTreeData.assignTreeChecked = res.data.checkList
    console.log(assignTreeData)
    //数据回显
    if (assignTreeData.assignTreeChecked.length > 0) {
      let newArr = []
      assignTreeData.assignTreeChecked.forEach(item => {
        checked(item, assignTreeData.list, newArr)
      })
      assignTreeData.assignTreeChecked = newArr
    }
  }
}
const checked = (id, data, newArr) => {
  data.forEach(item => {
    if (item.id === id) {
      if (item.children && item.children.length === 0) {
        newArr.push(item.id)
      }
    } else {
      if (item.children && item.children.length !== 0) {
        checked(id, item.children, newArr)
      }
    }
  })
}
//提交数据
const commitParm = reactive({
  roleId: '',
  list: []
})
//提交表单
const submitAssignForm = async () => {
  //获取选中菜单数据
  const checkIds = treeRef.value.getCheckedKeys()
  const halfCheckIds = treeRef.value.getHalfCheckedKeys()
  let ids = checkIds.concat(halfCheckIds)
  commitParm.list = ids
  if (ids.length === 0) {
    ElMessage.warning('请选择菜单')
    return
  }
  //判断是否已经选择菜单
  let res = await saveMenuApi(commitParm)
  if (res) {
    ElMessage.success('分配权限成功')
    assignFormShow.value = false
  }
}
//分配权限弹窗结束

onMounted(() => {
  nextTick(() => {
    tableHigh.value = window.innerHeight - 300
  })
  roleGet()
})
</script>

<template>
  <el-main>
    <!-- 搜索栏 -->
    <el-form :inline="true" :model="searchParm" size="default">
      <el-form-item>
        <el-input placeholder="请输入关键字" v-model="searchParm.roleName" />
      </el-form-item>
      <el-form-item>
        <el-button icon="Search" @click="searchBtn">查询</el-button>
        <el-button icon="Close" type="danger" plain @click="resetBtn"
          >重置</el-button
        >
        <el-button icon="Plus" type="primary" @click="addBtn">新增</el-button>
        <!-- 添加导出按钮 -->
        <el-button icon="Download" type="success" @click="exportExcel"
          >导出</el-button
        >
      </el-form-item>
    </el-form>
    <!-- 表格 -->
    <el-table :height="tableHigh" :data="roleList" style="width: 100%">
      <el-table-column type="selection" min-width="10%" />
      <el-table-column prop="name" label="角色" min-width="40%" />
      <el-table-column prop="comment" label="角色名称" min-width="60%" />
      <el-table-column label="操作" min-width="40%">
        <template #default="scope">
          <el-button
            link
            type="success"
            icon="Edit"
            size="small"
            @click="editBtn(scope.row)"
            >编辑</el-button
          >
          <el-button
            link
            type="primary"
            icon="Edit"
            size="small"
            @click="assignBtn(scope.row)"
            >分配菜单</el-button
          >
          <el-button
            link
            type="danger"
            icon="Delete"
            size="small"
            @click="deleteBtn(scope.row)"
            >删除</el-button
          >
        </template>
      </el-table-column>
      <!-- 分配菜单 -->
      <AssignTree ref="assignTree"></AssignTree>
    </el-table>
  </el-main>
  <!-- 分页 -->
  <el-pagination
    @size-change="sizeChange"
    @current-change="currentChange"
    v-model:current-page="searchParm.currentPage"
    :page-sizes="[10, 20, 30, 40]"
    :page-size="searchParm.pageSize"
    layout="total, sizes, prev, pager, next, jumper"
    :total="searchParm.total"
  >
  </el-pagination>
  <!-- 新增，编辑弹窗 -->
  <el-dialog v-model="addFormShow" :title="menuTitle" width="50%">
    <el-form
      :model="addModel"
      ref="addRef"
      :rules="rules"
      label-width="120px"
      size="default"
    >
      <el-form-item label="角色名称：" prop="roleName">
        <el-input v-model="addModel.roleName" placeholder="请输入角色名称" />
      </el-form-item>
      <el-form-item label="角色备注：" prop="roleComment">
        <el-input v-model="addModel.roleComment" placeholder="请输入角色描述" />
      </el-form-item>
    </el-form>
    <template #footer>
      <span class="dialog-footer">
        <el-button>取消</el-button>
        <el-button type="primary" @click="submitForm">提交</el-button>
      </span>
    </template>
  </el-dialog>
  <!-- 分配权限弹窗 -->
  <el-dialog v-model="assignFormShow" :title="assignTitle" width="40%">
    <template v-slot>
      <el-tree
        show-checkbox
        ref="treeRef"
        node-key="id"
        default-expand-all
        :default-checked-keys="assignTreeData.assignTreeChecked"
        :data="assignTreeData.list"
        :props="defaultProps"
      />
    </template>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="closeForm">取消</el-button>
        <el-button type="primary" @click="submitAssignForm">提交</el-button>
      </span>
    </template>
  </el-dialog>
</template>

<style scoped lang="scss"></style>
